package cn.eric.framework.utils.gson;

import com.google.gson.*;

import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

public class GsonUtil {
    private GsonUtil() {
    }

    public static Gson getGson() {
        GsonBuilder builder = new GsonBuilder();

        /**
         * 例子
         * 添加自定义的处理器
         */
        builder.registerTypeAdapter(Date.class, new EDate2MilliTsTypeAdapter());
        builder.registerTypeAdapter(Date.class, new EMilliTs2DateTypeAdapter());

        /**
         * 开启排除字段
         */
        builder.addSerializationExclusionStrategy(new ESerializationExclusionStrategy());
        builder.addDeserializationExclusionStrategy(new EDeserializationExclusionStrategy());

        return builder.create();
    }

    private static class EDate2MilliTsTypeAdapter implements JsonSerializer<Date> {
        @Override
        public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) {
            if (src != null) {
                return new JsonPrimitive(src.getTime());
            }
            return null;
        }
    }

    private static class EMilliTs2DateTypeAdapter implements JsonDeserializer<Date> {
        @Override
        public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            if (json != null) {
                return new Date(json.getAsJsonPrimitive().getAsLong());
            }
            return null;
        }
    }

    public static class EEnumTypeAdapter<T extends Enum> implements JsonSerializer<T>, JsonDeserializer<T> {
        @Override
        public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context) {
            if (Arrays.asList(src.getClass().getInterfaces()).contains(EEnum.class)) {
                return ((EEnum) src).serialize();
            } else {
                return new JsonPrimitive(src.ordinal());
            }
        }

        @Override
        public T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            try {
                Class clazz = Class.forName(typeOfT.getTypeName());
                if (Arrays.asList(clazz.getInterfaces()).contains(EEnum.class)) {
                    List<Object> list = Arrays.asList(clazz.getEnumConstants());
                    if (list.size() > 0) {
                        return (T) ((EEnum) list.get(0)).deserialize(json.getAsString());
                    }
                }
            } catch (ClassNotFoundException e) {
                return null;
            }
            return null;
        }
    }

    public interface EEnum<T extends Enum> {
        JsonElement serialize();

        T deserialize(String s);
    }

    public static void main(String[] args) {
    }
}
